// Define the Pipes namespace object
var Pipes = {};

// standard factory for creating Pipes.objects.* objects
Pipes.ajaxify = function(selector, options) {
    // define options as an empty has if it's not set
    options = options || {};

    switch($(selector).getTag()) {
        case 'a' :
			console.log(options['type']);
            switch (options['type']) {
                case 'RemoveModel' :
                    return new Pipes.objects.Anchor.RemoveModel($(selector));
                    break;
                
                case 'AddForm' :
                    return new Pipes.objects.Anchor.AddForm($(selector));
                    break;

                case 'EditForm' :
                    return new Pipes.objects.Anchor.EditForm($(selector));
                    break;

				case 'BrowseReplace' :
					return new Pipes.objects.Anchor.BrowseReplace($(selector));
					break;
            }

            return new Pipes.objects.Anchor($(selector));
            break;

        case 'form' :
            
            // definte requireValidation based on whether it has the 'requireValidation' 
            // class if it's not explicitly set
            options['requireValidation'] = options['requireValidation'] || $(selector).hasClass('requireValidation');
            return new Pipes.objects.Form(selector, options);
            break;
        
        case 'div' :
            switch (options['type']) {
                case 'AjaxifiedLinks' :
                    return new Pipes.objects.Div.AjaxifiedLinks($(selector));
                    break;
            }

        default:
            Pipes.error('Unable to ajaxify [' + $(selector).getTag() + '] element');
            break;
    }
};

Pipes.error = function(msg) {
    if (console != undefined) {
        console.log(msg);
    } else {
        alert(msg);
    }
}

Pipes.objects = {};

Pipes.objects.Div = {};
Pipes.objects.Div.AjaxifiedLinks = new Class({
    initialize: function(div) {
        this.element = div;
    },
    process:function() {
		$ES('a', this.element).each(function(anchor) {
			anchor.addEvent('click',  function(event) {
				switch (this.firstChild.nodeValue) {
					case 'edit':
						Pipes.ajaxify(this, {type:'EditForm'}).process();
						break;
					case 'delete':
						Pipes.ajaxify(this, {type: 'RemoveModel'}).process();
						break;
					default :
						Pipes.ajaxify(this, {type: 'BrowseReplace'}).process();
						break;
    	        }

				new Event(event).stop();
			});
		});
    }
});

Pipes.objects.Anchor = new Class({
    initialize: function(anchor) {
        this.anchor = anchor;
    },
    process: function() {
        alert('and do what exactly?');
        return false;
    }
});

Pipes.objects.Anchor.RemoveModel = Pipes.objects.Anchor.extend({
    initialize: function(anchor) {
        this.parent(anchor);
        this.row = $($($(this.anchor).parentNode).parentNode);
    },
    process: function() {
        var me = this;
        new Ajax(
            this.anchor.href,
            {method:'get', onComplete: function() { me.removeRow(); }}
        ).request();
        return false;
    },
    removeRow: function() {
        new Pipes.Fx.FadeOutAndRemove(this.row).toggle();
    },
});

Pipes.objects.Anchor.AddForm = Pipes.objects.Anchor.extend({
    initialize: function(anchor) {
        this.parent(anchor);
    },
    process: function() {
        var me = this;
        new Ajax(
            this.anchor.href + '?isAjax=true',
            {method:'get', onComplete:function(result) { me.onComplete(result) }}
        ).request();
        return false;
    },
    onComplete: function(result) {
        new Pipes.Fx.FadeInAndShow(new Element('div').setHTML(result), {where: this.anchor.parentNode}).toggle();
    },
});

Pipes.objects.Anchor.EditForm = Pipes.objects.Anchor.extend({
    initialize: function(anchor) {
        this.parent(anchor);
    },
    process: function() {
        var me = this;
        new Ajax(
            this.anchor.href + '?isAjax=true',
            {method:'get', onComplete:function(result) { me.onComplete(result) }}
        ).request();
        return false;
    },
    onComplete: function(result) {
        new Pipes.Fx.FadeInAndShow(new Element('div').setHTML(result), {where: 'dashboard_action'}).toggle();
    }
});

Pipes.objects.Anchor.BrowseReplace = Pipes.objects.Anchor.extend({
	initialize: function(anchor) {
		this.parent(anchor);
	},
	process: function() {
		var me = this;
		this.modal = new Pipes.objects.Modal($('dashboard_browse'));
		this.modal.show();
		new Ajax(
			me.anchor.href + '?isAjax=true',
			{method:'get', onComplete:function(result) { me.onComplete(result) }}
		).request();
		
		return false;
	},
	onComplete: function(result) {
		$('dashboard_browse').setHTML(result);
		Pipes.ajaxify($('dashboard_browse'), {type:'AjaxifiedLinks'}).process();
	}
});


Pipes.objects.Modal = new Class({
    initialize: function(container) {
        this.container = container;
        this.container.setStyles({
            'position':'relative',
            'display':'block'
        });
        this.modal = new Element('div');
        this.modal.addClass('loading');
        this.modal.setHTML('<div class="middle"><div class="inner"><p>Please wait...</p></div></div>');
        this.modal.setStyle('height', this.container.clientHeight+'px');
		this.modal.setOpacity(.8);
    },
    show: function() {
        this.container.adopt(this.modal);
    },
    remove: function() {
        this.container.removeChild(this.modal);
    },
});
Pipes.objects.Form = new Class({
    requireValidation: false,
    onComplete: function(result) {
        // update dashboard if available, otherwise replace
        var dashboard = $('dashboard_browse');
        var div = new Element('div').setHTML(result);
        if (dashboard !== false) {
            new Pipes.Fx.FadeOutAndRemove(this.form.parentNode.parentNode).toggle();
            div.id = 'dashboard_browse';
            dashboard.replaceWith(div);
        } else {
            this.form.replaceWith(div);
        }
    },
    loading: function() {
        this.loadingModal = new Pipes.objects.Modal(this.form);
        this.loadingModal.show();
    },
    initialize: function(selector, options) {
        var me = this;
        this.form = $(selector);
        if (options == undefined) {
            return;
        }

        this.form.action += '?isAjax=1';
        this.requireValidation = options['requireValidation'] || this.requireValidation;
        this.onComplete = options['onComplete'] || this.onComplete;
        this.loading = options['loading'] || this.loading;

    },
    process: function() {
        var me = this;
        this.loading();
        this.form.send({onComplete: function(result){me.onComplete(result);}});
        return false;
    },
});


Pipes.Fx = {};
Pipes.Fx.FadeOutAndRemove = new Class({
    initialize: function(selector, options) {
        this.element = $(selector);
        this.options = options || {};
        this.options['duration'] = this.options['duration'] || 500;
    },
    toggle: function() {
		new Fx.Style(this.element, 'opacity').start(1,0);
        var me = this;
        var removeNode = function() {
            me.element.remove();
        }.delay(this.options.duration);
    }
});
Pipes.Fx.FadeOutAndRemove.implement(new Chain);

Pipes.Fx.FadeInAndShow = new Class({
    initialize: function(selector, options) {
        this.element = $(selector);
        this.options = options || {};
        this.options.duration = this.options.duration || 500;
    },
    toggle: function() {
        $(this.options.where).adopt(this.element);
		this.element.setOpacity(0);
		new Fx.Style(this.element, 'opacity').start(0,1);
    }
});
Pipes.Fx.FadeInAndShow.implement(new Chain);
